﻿using FeiShu.Entity.Adapter.FeiShuWork;
using FeiShu.Entity.Common;
using FeiShu.IService.User;
using FeiShu.Site.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using SSharing.Frameworks.NetCore.Common.Consts;
using SSharing.Frameworks.NetCore.Common.Extends;
using System;
using System.Diagnostics;
using System.Web;

namespace FeiShu.Site.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly IUserService _userService;
        private readonly string appHomePage;
        private readonly string oAuthHost;
        private readonly string oAuthAppId;
        private readonly string redirectSite;
        private readonly string yxslCorpCode;
        private readonly string yxslApiKey;
        private readonly int loginType;
        private static readonly string CookieKey = "FeiShu.Login.UserDetailInfo";
        private readonly int cacheUserDetailHours;

        public HomeController(ILogger<HomeController> logger, IUserService userService)
        {
            _logger = logger;
            _userService = userService;
            IConfigurationBuilder builder = new ConfigurationBuilder();
            builder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);//reloadOnChange:true当配置更新了程序自动更新
            builder.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true);
            IConfigurationRoot configRoot = builder.Build();
            var yxslSection = configRoot.GetSection("YXSL");
            var feishuSection = configRoot.GetSection("FEISHU");

            oAuthHost = feishuSection["ApiHost"].TrimEnd(new char[] { '/' });
            oAuthAppId = feishuSection["AppID"];

            appHomePage = yxslSection["AppHomePage"].TrimEnd(new char[] { '/' });
            redirectSite = yxslSection["RedirectSite"].TrimEnd(new char[] { '/' });
            yxslCorpCode = yxslSection["CorpCode"];
            yxslApiKey = yxslSection["ApiKey"];
            loginType = yxslSection["LoginType"].ToInt(2);//默认邮箱登录
            cacheUserDetailHours = yxslSection["CacheUserDetailHours"].ToInt(4);
        }

        public IActionResult Index()
        {
            //验证cookie
            string cookieValue;
            HttpContext.Request.Cookies.TryGetValue(CookieKey, out cookieValue);
            if (!cookieValue.IsNullOrEmpty())
            {
                var userDetailRS = cookieValue.FromDES().FromJson<UserAccessTokenResponse>();

                //检查是否正常获取访问用户身份
                if (userDetailRS != null && userDetailRS.code == 0 && userDetailRS.data != null)
                {
                    var userID = GetUserID(userDetailRS);
                    var goToUrl = CreateGoToUrl(userID, userDetailRS.data.name);

                    _logger.LogInformation(string.Format("命中cookie，单点登录跳转链接地址：{0}", goToUrl));
                    return Redirect(goToUrl);
                }
            }

            Stopwatch stopwatch = Stopwatch.StartNew();
            var redirectUrl = HttpUtility.UrlEncode(string.Format("{0}/home/login", appHomePage));
            var oauth2Url = string.Format("{0}/open-apis/authen/v1/index?redirect_uri={1}&app_id={2}&state=Auth", oAuthHost, redirectUrl, oAuthAppId);
            stopwatch.Stop();

            _logger.LogInformation(string.Format("构造网页授权链接，链接地址:{0}，耗时:{1}ms", oauth2Url, stopwatch.ElapsedMilliseconds));
            return Redirect(oauth2Url);
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <returns></returns>
        public IActionResult Login(string code,string state)
        {
            if (state != "Auth") return null;
            var goToUrl = string.Empty;
            try
            {
                Stopwatch stopwatch1 = Stopwatch.StartNew();
                var getUserInfoRS = _userService.GetUserInfo(code);
                stopwatch1.Stop();
                _logger.LogInformation(string.Format("获取访问用户身份，code:{0}，detail:{1}，耗时:{2}ms", code, getUserInfoRS.ToJson(), stopwatch1.ElapsedMilliseconds));

                var userID = GetUserID(getUserInfoRS);
                goToUrl = CreateGoToUrl(userID, getUserInfoRS.data.name);

                //写cookie
                HttpContext.Response.Cookies.Append(CookieKey, getUserInfoRS.ToJson().ToDES(), new Microsoft.AspNetCore.Http.CookieOptions { Expires = DateTimeOffset.Now.AddHours(cacheUserDetailHours) });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, string.Format("单点登录跳转时发生异常，message:{0}", ex.Message));
            }

            _logger.LogInformation(string.Format("网页授权登录，单点登录跳转链接地址:{0}", goToUrl));
            return Redirect(goToUrl);
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
        private string GetUserID(UserAccessTokenResponse getUserDetailRS)
        {
            var userID = string.Empty;

            //userId
            if (loginType == (int)LoginType.UserID)
            {
                userID = getUserDetailRS.data.name;
            }
            if (loginType == (int)LoginType.Email)
            {
                userID = getUserDetailRS.data.email;
            }
            if (loginType == (int)LoginType.Mobile)
            {
                userID = getUserDetailRS.data.mobile.Replace("+86", "");
            }
            return userID;
        }
        private string CreateGoToUrl(string userID, string name)
        {
            var goToUrl = string.Empty;

            var sign = string.Format("{0}{1}{2}{3}", userID, yxslCorpCode, yxslApiKey, DateTime.Now.ToString(DateTimeTypeConst.DATE));
            goToUrl = string.Format("{0}?&user={1}&usertype={2}&name={3}&corpcode={4}&sign={5}&type=home", redirectSite, userID, loginType, name, yxslCorpCode, sign.ToMD5With32bit());

            return goToUrl;
        }
    }
}
